package cn.smxy.admin.controller;

import cn.smxy.admin.listener.ExcelDataListener;
import cn.smxy.admin.param.AdminUserParam;
import cn.smxy.admin.pojo.AdminUser;
import cn.smxy.admin.service.AdminService;
import cn.smxy.admin.excel.AdminUserExcel;
import cn.smxy.admin.util.LimitRequest;
import cn.smxy.admin.aop.log.Log;
import cn.smxy.param.PageParam;
import cn.smxy.util.R;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wf.captcha.utils.CaptchaUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Map;

@RestController
@RequestMapping
public class AdminController {

    @Autowired
    private AdminService adminService;

    /**
     * excel批量导入接口
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/save/batch")
    @Log(name = "excel批量导入")
    private R saveBatch(MultipartFile file) throws IOException {
        EasyExcel.read(file.getInputStream(), AdminUser.class,new ExcelDataListener()).sheet().doRead();
        return R.ok("导入成功");
    }

    /**
     * excel批量导出接口
     * @param response
     */
    @GetMapping("/export")
    @Log(name = "excel批量导出")
    private void export(HttpServletResponse response) throws IOException {
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("管理员名单", "UTF-8").replaceAll("\\+", "%20") + System.currentTimeMillis();
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            // 这里需要设置自适应列宽
            EasyExcel.write(response.getOutputStream(), AdminUserExcel.class)
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .autoCloseStream(Boolean.FALSE)
                    .sheet("sheet1").doWrite(adminService.getAll());
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = MapUtils.newHashMap();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            ObjectMapper mapper = new ObjectMapper();
            response.getWriter().println(mapper.writeValueAsString(map));
        }
    }

    /**
     * 生成验证码接口
     *
     * @param request
     * @param response
     * @throws IOException
     */
    @LimitRequest(count = 6)
    @GetMapping("/captcha")
    public void captcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 默认四个字符长度的验证码
        // 默认放入session key=captcha的位置
        response.setCharacterEncoding("UTF-8");
        CaptchaUtil.out(request,response);
    }

    /**
     * 管理员登录接口
     *
     * @param adminUserParam
     * @param result
     * @param session
     * @return
     */
    @PostMapping("/login")
    public Object login(@Validated AdminUserParam adminUserParam, BindingResult result, HttpSession session) {
        // 参数校验
        if (result.hasErrors()) {
            return R.fail("登录失败，核心参数为null");
        }
        // 校验验证码
        String verCode = adminUserParam.getVerCode();
        String captcha = (String) session.getAttribute("captcha");
        if (!verCode.equalsIgnoreCase(captcha)) {
            return R.fail("登录失败，验证码错误");
        }
        // 校验数据
        R r = adminService.login(adminUserParam);
        // 获取数据存储到session共享域，后期登录访问判断
        AdminUser adminUser = (AdminUser) r.getData();
        // 存储到session共域 key = userInfo 其他页面固定读取
        session.setAttribute("userInfo",adminUser);
        return r;
    }

    /**
     * 管理员退出登录接口
     *
     * @param session
     * @return
     */
    @GetMapping("/logout")
    public Object logout(HttpSession session) {
        // 清空session
        session.invalidate();
        return R.ok("退出登录成功");
    }

    /**
     * 分页查询管理员列表接口
     *
     * @param pageParam
     * @return
     */
    @GetMapping("/list")
    @Log(name = "获取管理员列表")
    public Object list(PageParam pageParam) {
        return adminService.list(pageParam);
    }

    /**
     * 批量删除接口
     *
     * @param adminIds
     * @return
     */
    @PostMapping("/remove/batch")
    @Log(name = "批量删除")
    public R removeBatch(String adminIds) {
        String[] strings = adminIds.split(",");
        Long[] ids = new Long[strings.length];
        for (int i = 0; i < strings.length; i++) {
            ids[i] = Long.parseLong(strings[i]);
            if(ids[i] == 1631453404263890956L) {
                return R.fail("ID为1631453404263890956的管理员不可删除!");
            }
        }
        return adminService.removeBatch(ids);
    }

    /**
     * 数据可视化测试接口
     * @return
     */
    @GetMapping("/echarts")
    public R echarts() {
        return adminService.echarts();
    }

    /**
     * 获取各作品评论数接口
     * @return
     */
    @GetMapping("/pie")
    public R pie(){
        return adminService.pie();
    }
}
